package com.xndc.netty.iec104.handler;

import com.xndc.netty.iec104.model.ASDU;
import com.xndc.netty.iec104.model.IEC104ControlFrame;
import com.xndc.netty.iec104.model.IEC104Frame;
import com.xndc.netty.iec104.model.IEC104InformationFrame;
import com.xndc.netty.iec104.model.InformationElement;
import com.xndc.netty.iec104.model.InformationObject;
import com.xndc.service.iec104.Iec104CommandService;
import com.xndc.service.iec104.Iec104ConnectionManager;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * IEC 104业务处理器
 */
@Slf4j
@Component
@Sharable
public class Iec104BusinessHandler extends SimpleChannelInboundHandler<IEC104Frame> {

    private final Iec104ConnectionManager connectionManager;

    @Autowired(required = false)
    private Iec104CommandService commandService;

    @Autowired
    public Iec104BusinessHandler(Iec104ConnectionManager connectionManager) {
        this.connectionManager = connectionManager;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("设备连接建立: {}", ctx.channel().remoteAddress());
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("设备连接断开: {}", ctx.channel().remoteAddress());
        // 先获取远程地址信息，然后查找设备ID后移除连接
        String remoteAddress = ctx.channel().remoteAddress().toString();
        // 这里需要添加根据地址找设备ID的逻辑，简化处理直接记录日志
        log.info("设备连接断开，地址: {}", remoteAddress);
        super.channelInactive(ctx);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, IEC104Frame frame) throws Exception {
        // 只处理信息帧，控制帧由Iec104SessionHandler处理
        if (!frame.isControlFrame() && frame instanceof IEC104InformationFrame) {
            IEC104InformationFrame infoFrame = (IEC104InformationFrame) frame;
            ASDU asdu = infoFrame.getAsdu();

            if (asdu != null) {
                // 直接使用远程地址作为设备ID
                String deviceId = ctx.channel().remoteAddress().toString();

                // 日志前添加分隔符
                log.info("—————————————————————— 收到IEC104帧 ——————————————————————");
                log.info("设备地址: {}", deviceId);

                // 处理不同类型的ASDU
                handleAsdu(ctx, deviceId, asdu, infoFrame);

                // 日志后添加分隔符
                log.info("—————————————————————— 处理完成 ——————————————————————");
                
            } else {
                log.warn("收到没有ASDU的信息帧");
            }
        }
    }

    /**
     * 处理不同类型的ASDU
     *
     * @param ctx       通道上下文
     * @param deviceId  设备ID
     * @param asdu      ASDU数据
     * @param infoFrame 信息帧
     */
    private void handleAsdu(ChannelHandlerContext ctx, String deviceId, ASDU asdu, IEC104InformationFrame infoFrame) {
        byte typeId = asdu.getTypeId();
        byte cot = asdu.getCot();

        log.info("处理ASDU: 设备={}, 类型={}, COT={}, 对象数={}",
                deviceId, typeId, cot, asdu.getInformationObjects().size());

        try {
            switch (typeId) {
                // ======== 监视方向过程信息 ========
                case 1:  // 单点信息
                    handleSinglePointInfo(deviceId, asdu);
                    break;
                    
                case 2:  // 带时标的单点信息
                    handleSinglePointInfoWithTimestamp(deviceId, asdu);
                    break;

                case 3:  // 双点信息
                    handleDoublePointInfo(deviceId, asdu);
                    break;
                    
                case 4:  // 带时标的双点信息
                    handleDoublePointInfoWithTimestamp(deviceId, asdu);
                    break;

                case 5:  // 步位置信息
                    handleStepPositionInfo(deviceId, asdu);
                    break;
                    
                case 6:  // 带时标的步位置信息
                    handleStepPositionInfoWithTimestamp(deviceId, asdu);
                    break;

                case 7:  // 32位串
                    handleBitStringInfo(deviceId, asdu);
                    break;
                    
                case 8:  // 带时标的32位串
                    handleBitStringInfoWithTimestamp(deviceId, asdu);
                    break;

                case 9:  // 测量值，归一化值
                    handleMeasurementInfo(deviceId, asdu);
                    break;
                    
                case 10: // 带时标的测量值，归一化值
                    handleMeasurementInfoWithTimestamp(deviceId, asdu);
                    break;

                case 11: // 测量值，标度化值
                    handleMeasurementInfo(deviceId, asdu);
                    break;
                    
                case 12: // 带时标的测量值，标度化值
                    handleMeasurementInfoWithTimestamp(deviceId, asdu);
                    break;

                case 13: // 测量值，短浮点数
                    handleMeasurementInfo(deviceId, asdu);
                    break;
                    
                case 14: // 带时标的测量值，短浮点数
                    handleMeasurementInfoWithTimestamp(deviceId, asdu);
                    break;
                    
                case 15: // 累积量
                    handleIntegratedTotals(deviceId, asdu);
                    break;
                    
                case 16: // 带时标的累积量
                    handleIntegratedTotalsWithTimestamp(deviceId, asdu);
                    break;
                    
                // ======== 带CP56Time2a时标的监视方向过程信息 ========
                case 30: // 带CP56Time2a时标的单点信息
                    handleSinglePointInfoWithCP56Time2a(deviceId, asdu);
                    break;
                    
                case 31: // 带CP56Time2a时标的双点信息
                    handleDoublePointInfoWithCP56Time2a(deviceId, asdu);
                    break;
                    
                case 32: // 带CP56Time2a时标的步位置信息
                    handleStepPositionInfoWithCP56Time2a(deviceId, asdu);
                    break;
                    
                case 33: // 带CP56Time2a时标的32位串
                    handleBitStringInfoWithCP56Time2a(deviceId, asdu);
                    break;
                    
                case 34: // 带CP56Time2a时标的归一化值
                    handleMeasurementInfoWithCP56Time2a(deviceId, asdu);
                    break;
                    
                case 35: // 带CP56Time2a时标的标度化值
                    handleMeasurementInfoWithCP56Time2a(deviceId, asdu);
                    break;
                    
                case 36: // 带CP56Time2a时标的短浮点数
                    handleMeasurementInfoWithCP56Time2a(deviceId, asdu);
                    break;
                    
                case 37: // 带CP56Time2a时标的累积量
                    handleIntegratedTotalsWithCP56Time2a(deviceId, asdu);
                    break;

                // ======== 控制方向过程信息 ========
                case 45: // 单点命令
                    handleSingleCommand(ctx, deviceId, asdu);
                    break;

                case 46: // 双点命令
                    handleDoubleCommand(ctx, deviceId, asdu);
                    break;

                case 48: // 步调节命令
                    handleRegulationCommand(ctx, deviceId, asdu);
                    break;

                case 50: // 设点命令，归一化值
                    handleSetpointCommand(ctx, deviceId, asdu);
                    break;

                case 51: // 设点命令，标度化值
                    handleSetpointCommand(ctx, deviceId, asdu);
                    break;

                case 58: // 设点命令，短浮点数
                    handleSetpointCommand(ctx, deviceId, asdu);
                    break;

                // ======== 系统信息 ========
                case 70: // 初始化结束
                    handleInitEnd(deviceId, asdu);
                    break;

                // ======== 参数传输 ========
                case 100: // 总召唤命令
                    handleGeneralInterrogation(ctx, deviceId, asdu);
                    break;

                case 101: // 计数量召唤命令
                    handleCounterInterrogation(ctx, deviceId, asdu);
                    break;
                    
                case 102: // 读命令
                    handleReadCommand(ctx, deviceId, asdu);
                    break;

                case 103: // 时钟同步命令
                    handleClockSync(ctx, deviceId, asdu);
                    break;

                case 105: // 复位进程命令
                    handleResetProcess(ctx, deviceId, asdu);
                    break;

                default:
                    log.warn(">> 未知ASDU类型: {} <<", typeId);
                    break;
            }

            // 对需要确认的I帧发送确认
            if (infoFrame.needsConfirmation() && commandService != null) {
                sendSFrame(ctx, deviceId, infoFrame);
            }

        } catch (Exception e) {
            log.error("处理ASDU异常: 类型={}, 设备={}, 错误={}", typeId, deviceId, e.getMessage(), e);
        }
    }

    /**
     * 处理单点信息(类型1)
     */
    private void handleSinglePointInfo(String deviceId, ASDU asdu) {
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            // 遍历所有信息元素
            for (InformationElement element : io.getElements()) {
                if (element.getValue() instanceof Boolean) {
                    boolean value = (Boolean) element.getValue();
                    // timestamp是byte[]类型，不是Date类型
                    byte[] timestampBytes = element.getTimestamp();
                    String timestampInfo = (timestampBytes != null) ? "有时标" : "无时标";
                    log.info("单点信息数据: 设备={}, IOA={}, 值={}, 时间={}",
                            deviceId, ioa, value, timestampInfo);

                    // TODO: 存储数据或通知其他服务
                }
            }
        }
    }

    /**
     * 处理双点信息(类型3)
     */
    private void handleDoublePointInfo(String deviceId, ASDU asdu) {
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                Object rawValue = element.getValue();
                String stateText = "未知";

                // 通常双点信息值为:
                // 0=中间状态, 1=确定开, 2=确定关, 3=不确定
                if (rawValue instanceof Number) {
                    int value = ((Number) rawValue).intValue();
                    switch (value) {
                        case 0:
                            stateText = "中间状态";
                            break;
                        case 1:
                            stateText = "确定开";
                            break;
                        case 2:
                            stateText = "确定关";
                            break;
                        case 3:
                            stateText = "不确定";
                            break;
                    }

                    log.info("双点信息数据: 设备={}, IOA={}, 值={}, 状态={}",
                            deviceId, ioa, value, stateText);

                    // TODO: 存储数据或通知其他服务
                }
            }
        }
    }

    /**
     * 处理步位置信息(类型5)
     */
    private void handleStepPositionInfo(String deviceId, ASDU asdu) {
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                if (element.getValue() instanceof Number) {
                    int value = ((Number) element.getValue()).intValue();
                    log.info("步位置信息: 设备={}, IOA={}, 值={}",
                            deviceId, ioa, value);

                    // TODO: 存储数据或通知其他服务
                }
            }
        }
    }

    /**
     * 处理位串信息(类型7)
     */
    private void handleBitStringInfo(String deviceId, ASDU asdu) {
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                Object value = element.getValue();
                log.info("位串信息: 设备={}, IOA={}, 值={}",
                        deviceId, ioa, value);

                // TODO: 存储数据或通知其他服务
            }
        }
    }

    /**
     * 处理测量值信息(类型9,11,13)
     */
    private void handleMeasurementInfo(String deviceId, ASDU asdu) {
        byte typeId = asdu.getTypeId();
        String valueType = typeId == 9 ? "归一化值" : (typeId == 11 ? "标度化值" : "短浮点数");

        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                Object rawValue = element.getValue();
                if (rawValue instanceof Number) {
                    double value = ((Number) rawValue).doubleValue();
                    log.info("测量值数据({}): 设备={}, IOA={}, 值={}",
                            valueType, deviceId, ioa, value);

                    // TODO: 存储数据到时序数据库或通知其他服务
                }
            }
        }
    }

    /**
     * 处理单点命令(类型45)
     */
    private void handleSingleCommand(ChannelHandlerContext ctx, String deviceId, ASDU asdu) {
        log.info(">> 开始处理单点命令(类型45) <<");
        log.info("单点命令基本信息: 设备={}, 传送原因={}, 对象数量={}", deviceId, asdu.getCot(), asdu.getInformationObjects().size());
        
        // 判断传送原因
        if (asdu.getCot() == 6) { // 激活
            // 执行命令并发送确认
            List<InformationObject> objects = asdu.getInformationObjects();
            log.info("信息对象数量: {}", objects.size());
            
            for (InformationObject io : objects) {
                int ioa = io.getAddress();
                log.info("处理IOA地址: {}", ioa);
                log.info("信息元素数量: {}", io.getElements().size());
                
                for (InformationElement element : io.getElements()) {
                    Object value = element.getValue();
                    log.info("元素值类型: {}, 值: {}", value != null ? value.getClass().getName() : "null", value);
                    
                    if (element.getValue() instanceof Boolean) {
                        boolean boolValue = (Boolean) element.getValue();
                        log.info("执行单点命令: 设备={}, IOA={}, 值={}", deviceId, ioa, boolValue);
                        
                        // TODO: 执行实际的控制命令
                        
                        // 发送命令确认 - 使用已有的方法，或者直接发送确认帧
                        if (commandService != null) {
                            sendCommandConfirmation(ctx, deviceId, asdu);
                            log.info("命令确认已发送");
                        } else {
                            log.warn("commandService为空，无法发送命令确认");
                        }
                    } else {
                        log.warn("元素值不是Boolean类型: {}, 而是 {}", value, value != null ? value.getClass().getName() : "null");
                    }
                }
            }
        } else if (asdu.getCot() == 8) { // 停止激活
            log.info("收到单点命令(停止激活): 设备={}", deviceId);
            // 通常不需要特殊处理
        } else {
            log.warn("未知的传送原因: {}", asdu.getCot());
        }
        
        log.info(">> 单点命令处理完成 <<");
    }

    /**
     * 处理双点命令(类型46)
     */
    private void handleDoubleCommand(ChannelHandlerContext ctx, String deviceId, ASDU asdu) {
        // 与单点命令类似，但值的解释不同
        if (asdu.getCot() == 6) { // 激活
            List<InformationObject> objects = asdu.getInformationObjects();
            for (InformationObject io : objects) {
                int ioa = io.getAddress();
                for (InformationElement element : io.getElements()) {
                    if (element.getValue() instanceof Number) {
                        int value = ((Number) element.getValue()).intValue();
                        String stateText = value == 1 ? "开" : (value == 2 ? "关" : "无效");

                        log.info("执行双点命令: 设备={}, IOA={}, 动作={}",
                                deviceId, ioa, stateText);

                        // TODO: 执行实际的控制命令

                        // 发送命令确认
                        if (commandService != null) {
                            sendCommandConfirmation(ctx, deviceId, asdu);
                        }
                    }
                }
            }
        }
    }

    /**
     * 处理步调节命令(类型48)
     */
    private void handleRegulationCommand(ChannelHandlerContext ctx, String deviceId, ASDU asdu) {
        if (asdu.getCot() == 6) { // 激活
            List<InformationObject> objects = asdu.getInformationObjects();
            for (InformationObject io : objects) {
                int ioa = io.getAddress();
                for (InformationElement element : io.getElements()) {
                    if (element.getValue() instanceof Number) {
                        int value = ((Number) element.getValue()).intValue();
                        log.info("执行步调节命令: 设备={}, IOA={}, 值={}",
                                deviceId, ioa, value);

                        // TODO: 执行实际的步调节命令

                        if (commandService != null) {
                            sendCommandConfirmation(ctx, deviceId, asdu);
                        }
                    }
                }
            }
        }
    }

    /**
     * 处理设点命令(类型50,51,58)
     */
    private void handleSetpointCommand(ChannelHandlerContext ctx, String deviceId, ASDU asdu) {
        byte typeId = asdu.getTypeId();
        String valueType = typeId == 50 ? "归一化值" : (typeId == 51 ? "标度化值" : "短浮点数");

        if (asdu.getCot() == 6) { // 激活
            List<InformationObject> objects = asdu.getInformationObjects();
            for (InformationObject io : objects) {
                int ioa = io.getAddress();
                for (InformationElement element : io.getElements()) {
                    if (element.getValue() instanceof Number) {
                        double value = ((Number) element.getValue()).doubleValue();
                        log.info("执行设点命令({}): 设备={}, IOA={}, 值={}",
                                valueType, deviceId, ioa, value);

                        // TODO: 执行实际的设点命令

                        if (commandService != null) {
                            sendCommandConfirmation(ctx, deviceId, asdu);
                        }
                    }
                }
            }
        }
    }

    /**
     * 处理初始化结束(类型70)
     */
    private void handleInitEnd(String deviceId, ASDU asdu) {
        log.info("设备初始化完成: {}", deviceId);
        // 可以在设备初始化完成后执行一些操作，如发送总召唤
        if (commandService != null) {
            // sendGeneralInterrogation方法不存在，使用已有的方法
            try {
                commandService.sendInterrogationCommand(deviceId);
            } catch (Exception e) {
                log.warn("发送总召唤失败: {}", e.getMessage());
            }
        }
    }

    /**
     * 处理总召唤命令(类型100)
     */
    private void handleGeneralInterrogation(ChannelHandlerContext ctx, String deviceId, ASDU asdu) {
        byte cot = asdu.getCot();
        if (cot == 6) { // 激活
            log.info("接收到总召唤命令: 设备={}", deviceId);

            // 发送确认
            if (commandService != null) {
                sendInterrogationConfirmation(ctx, deviceId, asdu);

                // 然后发送所有数据点信息
                // commandService.sendAllDataPoints(deviceId);
            }
        } else if (cot == 7) { // 确认激活
            log.info("接收到总召唤确认: 设备={}", deviceId);
        } else if (cot == 10) { // 终止激活
            log.info("总召唤完成: 设备={}", deviceId);
        }
    }

    /**
     * 处理计数量召唤命令(类型101)
     */
    private void handleCounterInterrogation(ChannelHandlerContext ctx, String deviceId, ASDU asdu) {
        byte cot = asdu.getCot();
        if (cot == 6) { // 激活
            log.info("接收到计数量召唤命令: 设备={}", deviceId);

            // 发送确认
            if (commandService != null) {
                // 自定义实现确认
                sendInterrogationConfirmation(ctx, deviceId, asdu);

                // 然后发送所有计数点信息
                // commandService.sendAllCounterPoints(deviceId);
            }
        }
    }

    /**
     * 处理时钟同步命令(类型103)
     */
    private void handleClockSync(ChannelHandlerContext ctx, String deviceId, ASDU asdu) {
        byte cot = asdu.getCot();
        if (cot == 6) { // 激活
            log.info("接收到时钟同步命令: 设备={}", deviceId);

            // 从ASDU中提取时间信息并同步本地时钟
            // ...

            // 发送确认
            if (commandService != null) {
                // 自定义实现确认
                sendClockSyncConfirmation(ctx, deviceId, asdu);
            }
        }
    }

    /**
     * 处理复位进程命令(类型105)
     */
    private void handleResetProcess(ChannelHandlerContext ctx, String deviceId, ASDU asdu) {
        byte cot = asdu.getCot();
        if (cot == 6) { // 激活
            log.info("接收到复位进程命令: 设备={}", deviceId);

            // 执行复位进程操作
            // ...

            // 发送确认
            if (commandService != null) {
                // 自定义实现确认
                sendCommandConfirmation(ctx, deviceId, asdu);
            }
        }
    }

    /**
     * 发送命令确认(通用方法)
     */
    private void sendCommandConfirmation(ChannelHandlerContext ctx, String deviceId, ASDU requestAsdu) {
        try {
            // 创建ASDU
            ASDU asdu = new ASDU();
            asdu.setTypeId(requestAsdu.getTypeId());
            asdu.setVsq(requestAsdu.getVsq());
            asdu.setCot((byte) 7);  // 传送原因: 确认激活(7)
            asdu.setCommonAddress(requestAsdu.getCommonAddress());

            // 复制信息对象
            asdu.setInformationObjects(requestAsdu.getInformationObjects());

            // 创建I帧
            IEC104InformationFrame frame = new IEC104InformationFrame();
            // 获取序列号 - 通过从ctx中获取Iec104SessionHandler
            Iec104SessionHandler sessionHandler = ctx.pipeline().get(Iec104SessionHandler.class);
            if (sessionHandler != null) {
                frame.setSendSequence(sessionHandler.getNextSendSequence());
            }
            frame.setReceiveSequence((short) 0); // 简化处理
            frame.setAsdu(asdu);

            // 发送确认帧
            Channel channel = ctx.channel();
            if (channel != null && channel.isActive()) {
                channel.writeAndFlush(frame);
                log.info("已发送命令确认: 设备={}, 类型={}", deviceId, requestAsdu.getTypeId());
            }
        } catch (Exception e) {
            log.error("发送命令确认失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 发送召唤确认
     */
    private void sendInterrogationConfirmation(ChannelHandlerContext ctx, String deviceId, ASDU requestAsdu) {
        // 与普通命令确认类似，但针对召唤类型
        sendCommandConfirmation(ctx, deviceId, requestAsdu);
    }

    /**
     * 发送时钟同步确认
     */
    private void sendClockSyncConfirmation(ChannelHandlerContext ctx, String deviceId, ASDU requestAsdu) {
        // 与普通命令确认类似，但针对时钟同步
        sendCommandConfirmation(ctx, deviceId, requestAsdu);
    }

    /**
     * 发送S帧确认
     */
    private void sendSFrame(ChannelHandlerContext ctx, String deviceId, IEC104InformationFrame infoFrame) {
        IEC104ControlFrame sFrame = new IEC104ControlFrame();
        sFrame.setControlType(IEC104ControlFrame.ControlType.S_FRAME);
        sFrame.setReceiveSequence((short) ((infoFrame.getSendSequence() + 1) % 32768));

        Channel channel = ctx.channel();
        if (channel != null && channel.isActive()) {
            channel.writeAndFlush(sFrame);
            log.debug("已发送S帧确认: 设备={}, N(R)={}", deviceId, sFrame.getReceiveSequence());
        }
    }

    /**
     * 处理带时标的单点信息(类型2)
     */
    private void handleSinglePointInfoWithTimestamp(String deviceId, ASDU asdu) {
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                if (element.getValue() instanceof Boolean) {
                    boolean value = (Boolean) element.getValue();
                    byte[] timestampBytes = element.getTimestamp();
                    log.info("带时标单点信息: 设备={}, IOA={}, 值={}, 有时标={}", 
                            deviceId, ioa, value, (timestampBytes != null));

                    // TODO: 存储数据或通知其他服务
                }
            }
        }
    }

    /**
     * 处理带时标的双点信息(类型4)
     */
    private void handleDoublePointInfoWithTimestamp(String deviceId, ASDU asdu) {
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                Object rawValue = element.getValue();
                String stateText = "未知";

                if (rawValue instanceof Number) {
                    int value = ((Number) rawValue).intValue();
                    switch (value) {
                        case 0: stateText = "中间状态"; break;
                        case 1: stateText = "确定开"; break;
                        case 2: stateText = "确定关"; break;
                        case 3: stateText = "不确定"; break;
                    }

                    byte[] timestampBytes = element.getTimestamp();
                    log.info("带时标双点信息: 设备={}, IOA={}, 值={}, 状态={}, 有时标={}",
                            deviceId, ioa, value, stateText, (timestampBytes != null));

                    // TODO: 存储数据或通知其他服务
                }
            }
        }
    }

    /**
     * 处理带时标的步位置信息(类型6)
     */
    private void handleStepPositionInfoWithTimestamp(String deviceId, ASDU asdu) {
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                if (element.getValue() instanceof Number) {
                    int value = ((Number) element.getValue()).intValue();
                    byte[] timestampBytes = element.getTimestamp();
                    log.info("带时标步位置信息: 设备={}, IOA={}, 值={}, 有时标={}",
                            deviceId, ioa, value, (timestampBytes != null));

                    // TODO: 存储数据或通知其他服务
                }
            }
        }
    }

    /**
     * 处理带时标的位串信息(类型8)
     */
    private void handleBitStringInfoWithTimestamp(String deviceId, ASDU asdu) {
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                Object value = element.getValue();
                byte[] timestampBytes = element.getTimestamp();
                log.info("带时标位串信息: 设备={}, IOA={}, 值={}, 有时标={}",
                        deviceId, ioa, value, (timestampBytes != null));

                // TODO: 存储数据或通知其他服务
            }
        }
    }

    /**
     * 处理带时标的测量值信息(类型10,12,14)
     */
    private void handleMeasurementInfoWithTimestamp(String deviceId, ASDU asdu) {
        byte typeId = asdu.getTypeId();
        String valueType = typeId == 10 ? "归一化值" : (typeId == 12 ? "标度化值" : "短浮点数");

        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                Object rawValue = element.getValue();
                if (rawValue instanceof Number) {
                    double value = ((Number) rawValue).doubleValue();
                    byte[] timestampBytes = element.getTimestamp();
                    log.info("带时标测量值({}): 设备={}, IOA={}, 值={}, 有时标={}",
                            valueType, deviceId, ioa, value, (timestampBytes != null));

                    // TODO: 存储数据到时序数据库或通知其他服务
                }
            }
        }
    }

    /**
     * 处理累积量(类型15)
     */
    private void handleIntegratedTotals(String deviceId, ASDU asdu) {
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                if (element.getValue() instanceof Number) {
                    long value = ((Number) element.getValue()).longValue();
                    log.info("累积量: 设备={}, IOA={}, 值={}",
                            deviceId, ioa, value);

                    // TODO: 存储数据或通知其他服务
                }
            }
        }
    }

    /**
     * 处理带时标的累积量(类型16)
     */
    private void handleIntegratedTotalsWithTimestamp(String deviceId, ASDU asdu) {
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                if (element.getValue() instanceof Number) {
                    long value = ((Number) element.getValue()).longValue();
                    byte[] timestampBytes = element.getTimestamp();
                    log.info("带时标累积量: 设备={}, IOA={}, 值={}, 有时标={}",
                            deviceId, ioa, value, (timestampBytes != null));

                    // TODO: 存储数据或通知其他服务
                }
            }
        }
    }

    /**
     * 处理带CP56Time2a时标的单点信息(类型30)
     */
    private void handleSinglePointInfoWithCP56Time2a(String deviceId, ASDU asdu) {
        // 类似于handleSinglePointInfoWithTimestamp，但时标格式不同
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                if (element.getValue() instanceof Boolean) {
                    boolean value = (Boolean) element.getValue();
                    byte[] timestampBytes = element.getTimestamp();
                    log.info("带CP56Time2a时标单点信息: 设备={}, IOA={}, 值={}, 有时标={}",
                            deviceId, ioa, value, (timestampBytes != null));

                    // TODO: 存储数据或通知其他服务
                }
            }
        }
    }

    /**
     * 处理带CP56Time2a时标的双点信息(类型31)
     */
    private void handleDoublePointInfoWithCP56Time2a(String deviceId, ASDU asdu) {
        // 实现类似于handleDoublePointInfoWithTimestamp
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                if (element.getValue() instanceof Number) {
                    int value = ((Number) element.getValue()).intValue();
                    String stateText;
                    switch (value) {
                        case 0: stateText = "中间状态"; break;
                        case 1: stateText = "确定开"; break;
                        case 2: stateText = "确定关"; break;
                        case 3: stateText = "不确定"; break;
                        default: stateText = "未知状态";
                    }
                    
                    byte[] timestampBytes = element.getTimestamp();
                    log.info("带CP56Time2a时标双点信息: 设备={}, IOA={}, 值={}, 状态={}, 有时标={}",
                            deviceId, ioa, value, stateText, (timestampBytes != null));

                    // TODO: 存储数据或通知其他服务
                }
            }
        }
    }

    /**
     * 处理带CP56Time2a时标的步位置信息(类型32)
     */
    private void handleStepPositionInfoWithCP56Time2a(String deviceId, ASDU asdu) {
        // 实现类似于handleStepPositionInfoWithTimestamp
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                if (element.getValue() instanceof Number) {
                    int value = ((Number) element.getValue()).intValue();
                    byte[] timestampBytes = element.getTimestamp();
                    log.info("带CP56Time2a时标步位置信息: 设备={}, IOA={}, 值={}, 有时标={}",
                            deviceId, ioa, value, (timestampBytes != null));

                    // TODO: 存储数据或通知其他服务
                }
            }
        }
    }

    /**
     * 处理带CP56Time2a时标的位串信息(类型33)
     */
    private void handleBitStringInfoWithCP56Time2a(String deviceId, ASDU asdu) {
        // 实现类似于handleBitStringInfoWithTimestamp
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                Object value = element.getValue();
                byte[] timestampBytes = element.getTimestamp();
                log.info("带CP56Time2a时标位串信息: 设备={}, IOA={}, 值={}, 有时标={}",
                        deviceId, ioa, value, (timestampBytes != null));

                // TODO: 存储数据或通知其他服务
            }
        }
    }

    /**
     * 处理带CP56Time2a时标的测量值信息(类型34,35,36)
     */
    private void handleMeasurementInfoWithCP56Time2a(String deviceId, ASDU asdu) {
        byte typeId = asdu.getTypeId();
        String valueType = typeId == 34 ? "归一化值" : (typeId == 35 ? "标度化值" : "短浮点数");

        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                Object rawValue = element.getValue();
                if (rawValue instanceof Number) {
                    double value = ((Number) rawValue).doubleValue();
                    byte[] timestampBytes = element.getTimestamp();
                    log.info("带CP56Time2a时标测量值({}): 设备={}, IOA={}, 值={}, 有时标={}",
                            valueType, deviceId, ioa, value, (timestampBytes != null));

                    // TODO: 存储数据或通知其他服务
                }
            }
        }
    }

    /**
     * 处理带CP56Time2a时标的累积量(类型37)
     */
    private void handleIntegratedTotalsWithCP56Time2a(String deviceId, ASDU asdu) {
        // 实现类似于handleIntegratedTotalsWithTimestamp
        List<InformationObject> objects = asdu.getInformationObjects();
        for (InformationObject io : objects) {
            int ioa = io.getAddress();
            for (InformationElement element : io.getElements()) {
                if (element.getValue() instanceof Number) {
                    long value = ((Number) element.getValue()).longValue();
                    byte[] timestampBytes = element.getTimestamp();
                    log.info("带CP56Time2a时标累积量: 设备={}, IOA={}, 值={}, 有时标={}",
                            deviceId, ioa, value, (timestampBytes != null));

                    // TODO: 存储数据或通知其他服务
                }
            }
        }
    }

    /**
     * 处理读命令(类型102)
     */
    private void handleReadCommand(ChannelHandlerContext ctx, String deviceId, ASDU asdu) {
        byte cot = asdu.getCot();
        if (cot == 5) { // 请求或被请求
            log.info("接收到读命令: 设备={}", deviceId);
            
            List<InformationObject> objects = asdu.getInformationObjects();
            for (InformationObject io : objects) {
                int ioa = io.getAddress();
                log.info("读取IOA={} 的数据", ioa);
                
                // TODO: 读取指定地址的数据并回复
                // 这里需要查询数据并以ASDU类型1,3,5,9,11,13等回复
                if (commandService != null) {
                    // 将COT设置为5(被请求)，并发送数据
                    // commandService.sendDataForIoa(deviceId, ioa, (byte)5);
                }
            }
        }
    }
} 